package srv

import (
	"background/model/back/entity"
	"background/model/back/repo"
	"background/utilx/authx"
	"background/utilx/cachex"
	"context"
	"time"
)

func (r CloudUser) emailInfo(ctx context.Context, rec entity.CloudUser) (*entity.CloudUser, error) {
	//u := rec.Act
	first, err := r.db.CloudUser.WithContext(ctx).Debug().Where(repo.CloudUser.Email.Eq(rec.Email)).First()
	if err != nil {
		return nil, err
	}
	return first, nil
}
func (r CloudUser) CacheEmailInfo(ctx context.Context, rec entity.CloudUser) (*entity.CloudUser, error) {
	return cachex.Aopx[*entity.CloudUser](false, false, r.redisx, entity.CacheKey(entity.CacheTypeUser, rec.Email), 24*time.Minute, func() (*entity.CloudUser, error) {
		return r.emailInfo(ctx, rec)
	})
}

func (r CloudUser) Login(ctx context.Context, rec entity.CloudUser) (string, error) {
	info, err := r.CacheEmailInfo(ctx, rec)
	if err != nil {
		return "", err
	}
	err = entity.UserCodeErr(r.loginFilter(ctx, rec, *info))
	if err != nil {
		return "", err
	}
	token, err := cachex.Aopx[string](false, false, r.redisx, entity.CacheKey(entity.CacheTypeUser, rec.Email, entity.FlagToken), 24*time.Hour, func() (string, error) {
		claims, err := authx.CreatJwtTokenWithClaims([]byte("asd"), time.Hour, authx.CustomClaims[entity.CloudUser]{
			Data: *info,
		})
		return claims, err
	})
	if err != nil {
		return "", err
	}
	claims, err := authx.ParseWithClaims[entity.CloudUser]([]byte("asd"), token)
	if err != nil {
		return "", err
	}
	r.loginFilter(ctx, rec, claims.Data)
	return token, nil
}
func (r CloudUser) loginFilter(ctx context.Context, rec, data entity.CloudUser) int {
	if rec.Password != data.Password {
		return entity.ErrCodeUserNotFound
	}
	if data.Banned != 0 {
		return entity.ErrCodeUserBanned
	}
	return 0
}

func (r CloudUser) Register(ctx context.Context, rec entity.CloudUser) error {
	return r.InsertOne(ctx, rec)
}
func (r CloudUser) ResetPassword(ctx context.Context, rec entity.CloudUser) error {
	_, err := r.db.CloudUser.WithContext(ctx).Where(
		repo.CloudUser.ID.Eq(rec.ID),
		repo.CloudUser.Email.Eq(rec.Email),
	).UpdateSimple(repo.CloudUser.Password.Value(rec.Password))
	if err != nil {
		return err
	}
	return nil
}
